package com.bifrost.web.controller;

import com.alibaba.fastjson.JSON;
import com.bifrost.annotation.Authorization;
import com.bifrost.annotation.CurrentStore;
import com.bifrost.annotation.CurrentUser;
import com.bifrost.entity.*;
import com.bifrost.exception.InventoryUnavailableException;
import com.bifrost.model.promotion.PromotionModel;
import com.bifrost.common.model.ResultModel;
import com.bifrost.model.promotion.SeckillModel;
import com.bifrost.model.promotion.SeckillTimeModel;
import com.bifrost.model.ro.OrderPointRO;
import com.bifrost.service.CustomerService;
import com.bifrost.service.ProductSkuService;
import com.bifrost.service.PromotionService;
import com.bifrost.service.StoreService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author rangf
 * @date 2018/3/5
 */
@Api("促销相关接口")
@RestController
@RequestMapping("/api/promotion")
public class PromotionController {

    @Autowired
    PromotionService promotionService;
    @Autowired
    ProductSkuService productSkuService;
    @Autowired
    CustomerService customerService;
    @Autowired
    StoreService storeService;
    private Logger logger = LoggerFactory.getLogger(PromotionController.class);

    @ApiOperation(value = "获取团购、积分商城列表")
    @GetMapping("/list")
    public ResultModel promotions(@CurrentStore Long storeId, @RequestParam String promotionType) {
        if (storeId != null) {
            MerchantStore store = storeService.getMerchantStore(storeId);
            List<PromotionModel> promotions = promotionService.list(store, promotionType);
            if (CollectionUtils.isNotEmpty(promotions)) {
                promotions = promotions.stream().sorted(Comparator.comparing(PromotionModel::getStockAvalible)).collect(Collectors.toList());
            }
            return ResultModel.ok().put("promotions", promotions);
        }
        return ResultModel.ok().put("promotions", null);
    }

    @ApiOperation(value = "根据获取秒杀开始时间获取列表")
    @GetMapping("/seckill/list")
    public ResultModel seckill(@CurrentStore Long storeId, @RequestParam String startTime) {
        SeckillModel model = null;
        try {
            if (startTime.matches("[0-9]+")) {
                Date start = new Date();
                start.setTime(Long.valueOf(startTime));
                MerchantStore store = storeService.getMerchantStore(storeId);
                model = promotionService.seckillList(store, start);
            }
        } catch (Exception e) {
            logger.error("seckill startTime is out of bounds");
        }
        return ResultModel.ok().put("model", model);
    }

    @ApiOperation(value = "获取秒杀开始时间戳")
    @GetMapping("/seckill/times")
    public ResultModel times(@CurrentStore Long storeId) {
        List<SeckillTimeModel> seckillTimes = promotionService.seckillTimes(storeId);
        Date now = new Date();
        return ResultModel.ok()
                .put("seckillTimes", seckillTimes)
                .put("currentTime", now);
    }

    @ApiOperation(value = "返回促销信息明细")
    @GetMapping("/promotion")
    public ResultModel promotion(@RequestParam Long promotionSkuId) {
        PromotionModel promotionModel = promotionService.promotion(promotionSkuId);
        List skus = promotionModel.getSkus();
        List productOptions = promotionModel.getProductOptions();
        promotionModel.setSkus(null);
        promotionModel.setProductOptions(null);
        return ResultModel.ok()
                .put("promotion", promotionModel)
                .put("skus", skus)
                .put("productOptions", productOptions);
    }

    @Authorization
    @ApiOperation(value = "积分兑换确认")
    @GetMapping("/exchange/confirm")
    public ResultModel confirmExchange(@CurrentUser Long userId, @RequestParam String data) {
        OrderPointRO ro = null;
        try {
            ro = JSON.parseObject(data, OrderPointRO.class);
        } catch (Exception e) {
            return ResultModel.error("无效兑换");
        }
        String paramMsg = promotionService.validateExchangeParam(ro);
        if (StringUtils.isEmpty(paramMsg)) {
            ProductSku sku = productSkuService.getSkuById(ro.getProductSkuId());
            Promotion promotion = promotionService.find(ro.getPromotionId());
            PromotionSku promotionSku = promotionService.findByPromotionAndSku(promotion, sku);
            if (promotionSku != null) {
                    ro.setSkuName(sku.getSkuName());
                    ro.setImageUrl(productSkuService.getDefaultSkuMedia(sku));
                    ro.setSalePrice(sku.getSalePrice());
                    ro.setBounsPoints(promotionSku.getPromotionPoint());
                    return ResultModel.ok().put("data", ro);
            }
            return ResultModel.error("兑换失败");
        }
        return ResultModel.error(paramMsg);
    }

    @Authorization
    @ApiOperation(value = "积分兑换")
    @PostMapping("/exchange")
    public ResultModel exchange(@CurrentUser Long userId, @RequestParam String data) {
        Customer customer = customerService.findCustomer(userId);
        OrderPointRO ro = null;
        try {
            ro = JSON.parseObject(data, OrderPointRO.class);
        } catch (Exception e) {
            return ResultModel.error("无效兑换");
        }
        String paramMsg = promotionService.validateExchangeParam(ro);
        if (StringUtils.isEmpty(paramMsg)) {
            ProductSku sku = productSkuService.getSkuById(ro.getProductSkuId());
            Promotion promotion = promotionService.find(ro.getPromotionId());
            PromotionSku promotionSku = promotionService.findByPromotionAndSku(promotion, sku);
            if (promotionSku != null) {
                String dataMsg = promotionService.validateExchange(customer, promotionSku, ro);
                if (StringUtils.isEmpty(dataMsg)) {
                    Order order = null;
                    try {
                        order = promotionService.exchange(customer, promotionSku, ro);
                    } catch (InventoryUnavailableException e) {
                        return ResultModel.error(e.getMessage());
                    }
                    return ResultModel.ok().put("data", order.getOrderId());
                }
                return ResultModel.error(dataMsg);
            }
            return ResultModel.error("兑换失败");
        }
        return ResultModel.error(paramMsg);
    }

}
